﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using MiniX.API.Data;
using MiniX.Models;
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Senparc.CO2NET.Extensions;
using MiniX.Utility.Helper;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Reflection;
using MiniX.API.Filters;
using MySqlX.XDevAPI.Relational;
using Microsoft.IdentityModel.Tokens;
using Serilog;

namespace MiniX.API.Controllers
{
    /// <summary>
    /// 微信相关，定义了CURD相关操作
    /// </summary>
    [Produces("application/json")]
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class WeChatController : BaseController<WeChatController>
    {
        /// <summary>
        /// WeChatController
        /// </summary>
        public WeChatController(MiniXApiContext context, IHttpContextAccessor httpContextAccessor) : base(context, httpContextAccessor)
        {

        }
        /// <summary>
        /// 微信授权登陆
        /// </summary>
        /// <param name="code">微信小程序获取的CODE</param>
        /// <returns></returns>
        [Route("/api/wechat/openid")]
        [AllowAnonymous]
        [HttpGet]
        public IActionResult OpenId(string code)
        {
            try
            {
                var app_id = "";
                var app_secret = "";
                var setting_info = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 300);
                if (setting_info != null)
                {
                    app_id = setting_info.info_value;
                }
                var setting_info2 = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 301);
                if (setting_info2 != null)
                {
                    app_secret = setting_info2.info_value;
                }

                WeChatAppDecrypt wechatDecrypt = new WeChatAppDecrypt(app_id, app_secret);
                var result = wechatDecrypt.GetOpenIdAndSessionKeyString(code);

                string open_id = "";
                string session_key = "";
                JObject? obj = null;
                try
                {
                    obj = JsonConvert.DeserializeObject(result) as JObject;
                    if (obj != null)
                    {
                        open_id = obj["openid"]!.ToString();
                        session_key = obj["session_key"]!.ToString();
                    }
                }
                catch (Exception ex)
                {
                    log.Error(" -> 解析OPENID", ex);
                }

                var data = new
                {
                    open_id = open_id,
                    session_key = session_key
                };

                return Json(new { code = 0, msg = "授权成功！", data = data });
            }
            catch (Exception ex)
            {
                log.Error(" -> OpenId", ex);
                return Json(new { code = 1, errcode = (int)ENUMHelper.ExceptionType.Login, errmsg = ex.Message });
            }
        }

        /// <summary>
        /// 微信授权登陆
        /// </summary>
        /// <param name="code">微信小程序获取的CODE</param>
        /// <returns></returns>
        [Route("/api/wechat/login")]
        [AllowAnonymous]
        [HttpGet]
        public async Task<IActionResult> Login(string code)
        {
            string result = "";

            try
            {
                var app_id = "";
                var app_secret = "";
                var setting_info = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 300);
                if (setting_info != null)
                {
                    app_id = setting_info.info_value;
                }
                var setting_info2 = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 301);
                if (setting_info2 != null)
                {
                    app_secret = setting_info2.info_value;
                }

                WeChatAppDecrypt wechatDecrypt = new WeChatAppDecrypt(app_id, app_secret);
                result = wechatDecrypt.GetOpenIdAndSessionKeyString(code);

                string open_id = "";
                string session_key = "";
                JObject? obj = null;
                try
                {
                    obj = JsonConvert.DeserializeObject(result) as JObject;
                    if (obj != null)
                    {
                        open_id = obj["openid"]!.ToString();
                        session_key = obj["session_key"]!.ToString();
                    }
                }
                catch (Exception ex)
                {
                    log.Error(" -> 解析OPENID", ex);
                }

                var access_token = MiniX.Utility.Helper.WeChatAppDecrypt.GetAccessToken(MiniX.Utility.Pay.WeChat.WeChatConfig.APPID, MiniX.Utility.Pay.WeChat.WeChatConfig.SERCRET);
                var mobile = "188" + Utility.Helper.CommonHelper.GenerateRandomNum(8);
                var client_ip = Request.HttpContext.Connection.RemoteIpAddress!.MapToIPv4().ToString();

                var item = await _context.mini_members.FirstOrDefaultAsync(t => t.open_id == open_id!.ToString() && !string.IsNullOrEmpty(t.open_id));
                if (item == null)
                {
                    return Json(new { code = 0, msg = "登录成功！", open_id = open_id, session_key = session_key});
                }
                else
                {
                    var token = JwtFilter.GetToken(item.member_id.ToString(), item.member_account!.ToString());

                    // 更新TOKEN
                    item.member_token = token;
                    _context.mini_members.Update(item);
                    _context.SaveChanges();
                    LogFilter.AddLogs(_context, log, 2, item.member_id, ENUMHelper.ExceptionType.Login.ToString(), "登录成功！", client_ip, token);

                    return Json(new { code = 0, msg = "登录成功！", token = token, open_id = open_id, session_key = session_key, data = item });
                }
            }
            catch (Exception ex)
            {
                log.Error(" -> Login", ex);
                return Json(new { code = 1, errcode = (int)ENUMHelper.ExceptionType.Login, errmsg = ex.Message });
            }
        }

        /// <summary>
        /// 微信获取手机号码
        /// </summary>
        /// <returns></returns>
        [Route("/api/wechat/phone")]
        [HttpPost]
        public IActionResult GetPhone([FromBody] WechatLoginInfo wechat)
        {
            try
            {
                log.Information("invite_member_id=" + wechat.invite_member_id);

                if (wechat != null)
                {
                    var app_id = "";
                    var app_secret = "";
                    var setting_info = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 300);
                    if (setting_info != null)
                    {
                        app_id=setting_info.info_value;
                    }
                    var setting_info2 = _context.mini_setting_info.FirstOrDefault(t => t.setting_info_id == 301);
                    if (setting_info2 != null)
                    {
                        app_secret = setting_info2.info_value;
                    }

                    WeChatAppDecrypt wechatDecrypt = new WeChatAppDecrypt(app_id, app_secret);
                    if (wechatDecrypt != null)
                    {
                        var session_key = wechat.code; // 借用code 传 Session_key
#pragma warning disable CS0612 // 类型或成员已过时
                        var result = wechatDecrypt.DecryptToJson(string.IsNullOrEmpty(wechat.encryptedData) ? "" : wechat.encryptedData, string.IsNullOrEmpty(wechat.iv) ? "" : wechat.iv, string.IsNullOrEmpty(session_key) ? "" : session_key);
#pragma warning restore CS0612 // 类型或成员已过时
                        // {\"phoneNumber\":\"15000772515\",\"purePhoneNumber\":\"15000772515\",\"countryCode\":\"86\",\"watermark\":{\"timestamp\":1685772199,\"appid\":\"wx965e56faa5cfb06f\"}}"}
                        // log.Information("result=" + result);
                        // 更新手机号
                        string mobile_phone = "";
                        JObject obj = (JObject)JsonConvert.DeserializeObject(result)!;
                        if (obj != null)
                        {
                            mobile_phone = obj["phoneNumber"]!.ToString();
                        }
                        var item = _context.mini_members.FirstOrDefault(t => t.member_account!.Equals(mobile_phone));
                        if (item != null)
                        {
                            item.open_id = wechat.open_id;
                            item.member_account = mobile_phone;
                            if (string.IsNullOrEmpty(item.member_name))
                            {
                                item.member_name = mobile_phone;
                                item.real_name = mobile_phone;
                            }
                            item.mobile_phone = mobile_phone;
                            _context.mini_members.Update(item);
                            _context.SaveChangesAsync();

                            var token = JwtFilter.GetToken(item.member_id.ToString(), item.member_account!.ToString());
                            return Json(new { code = 0, msg = "注册成功", data = result, member = item, token = token });
                        }
                        else
                        {
                            // 注册新用户
                            var members = new Members()
                            {
                                open_id = wechat.open_id!.ToString(),
                                member_account = mobile_phone,
                                mobile_phone = mobile_phone,
                                member_password = MiniX.Utility.Helper.MD5Helper.MD5Encrypt32(mobile_phone),
                                member_name = mobile_phone,
                                real_name = mobile_phone,
                                gender_id = 3,
                                member_avatar = "",
                                member_birth = "",
                                member_job = "",
                                invite_member_id = wechat.invite_member_id,
                                invite_code = MiniX.Utility.Helper.CommonHelper.GenerateRandomNum(6),
                                share_qrcode = "",
                                source_id = 3,
                                medium_id = 1,
                                member_intro = "",
                                member_status = true,
                                type_id = 1,
                                country_name = "",
                                province_name = "",
                                city_name = "",
                                district_name = "",
                                member_token = "",
                                encrypt_token = "",
                                member_remark = "",
                                created_at = DateTime.Now
                            };
                            _context.mini_members.Add(members);
                            _context.SaveChanges();

                            var member_id = members.member_id;
                            log.Information("register member_id=" + member_id);
                            var item_members = _context.mini_members.FirstOrDefault(t => t.member_id == member_id);

                            // 新用户添加一条积分记录
                            try
                            {
                                var point = new PointMembers()
                                {
                                    member_id = member_id,
                                    total_point = 0,
                                    available_point = 0,
                                    froze_point = 0,
                                    created_at = DateTime.Now
                                };
                                _context.mini_point_members.Add(point);
                                _context.SaveChanges();
                            }
                            catch (Exception ex)
                            {
                                log.Error(ex, "新用户添加一条积分记录");
                            }

                            // 生成分享二维码
                            try
                            {
                                if (item_members != null)
                                {
                                    // 生成路径及图片名
                                    var saveDir = MiniX.API.Filters.AppSettingsFilter.GetSetting("Upload:PATH");
                                    var tempPath = saveDir + "\\" + DateTime.Now.Year + "\\" + DateTime.Now.ToString("MMdd") + "\\";
                                    if (!Directory.Exists(tempPath))
                                    {
                                        Directory.CreateDirectory(tempPath);
                                    }
                                    var extension = ".png";
                                    var newFileName = DateTime.Now.ToString("yyyyMMddHHmmss") + MiniX.Utility.Helper.CommonHelper.GenerateRandomNum(6);
                                    var savePath = tempPath + newFileName + extension;
                                    var returnPath = "/" + DateTime.Now.Year + "/" + DateTime.Now.ToString("MMdd") + "/" + newFileName + extension;

                                    if (!Directory.Exists(tempPath))
                                    {
                                        Directory.CreateDirectory(tempPath);
                                    }
                                    if (System.IO.File.Exists(savePath))
                                    {
                                        System.IO.File.Delete(savePath);
                                    }

                                    // 生成二维码
                                    try
                                    {
                                        WXQRCode.GetQRCodePath("/pages/home/home?invite_member_id=" + member_id, savePath, 1280);
                                    }
                                    catch (Exception ex)
                                    {
                                        log.Fatal(ex, " -> 生成二维码");
                                    }

                                    // 更新至数据库
                                    try
                                    {
                                        item_members.share_qrcode = returnPath;
                                        _context.mini_members.Update(item_members);
                                        _context.SaveChanges();
                                    }
                                    catch (Exception ex)
                                    {
                                        log.Fatal(ex, " -> 更新至数据库");
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                log.Error(ex, "生成分享二维码");
                            }

                            var token = JwtFilter.GetToken(members.member_id.ToString(), members.member_account!.ToString());

                            return Json(new { code = 0, msg = "注册成功", data = result, member = item_members, token = token });
                        }
                    }
                    else
                    {
                        return Json(new { code = 0, msg = "获取手机号失败" });
                    }
                }
                else
                {
                    return Json(new { code = 0, msg = "获取手机号失败" });
                }
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, errcode = (int)ENUMHelper.ExceptionType.Login, errmsg = ex.Message });
            }
        }
    }
}
